home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / ftp / bkgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-17  |  29.6 KB  |  1,113 lines

  1. /*    Background procedures for rcp and ftp
  2. *****************************************************************
  3. *    NCSA Telnet for the Macintosh                                *
  4. *                                                                *
  5. *    National Center for Supercomputing Applications                *
  6. *    Software Development Group                                    *
  7. *    152 Computing Applications Building                            *
  8. *    605 E. Springfield Ave.                                        *
  9. *    Champaign, IL  61820                                        *
  10. *                                                                *
  11. *    Copyright (c) 1986-1992,                                    *
  12. *    Board of Trustees of the University of Illinois                *
  13. *****************************************************************
  14. * Revisions:
  15. * 11/86          Tim Krauskopf
  16. * 7/92    Telnet 2.6: added global structures, cleaned up defines   Scott Bulmahn
  17. *
  18. *
  19. */
  20.  
  21.  
  22. #ifdef MPW
  23. #pragma segment FTPServer
  24. #endif
  25.  
  26. #include <stdio.h>
  27. #include <string.h>
  28.  
  29. #include <Memory.h>
  30. #include <CType.h>
  31. #include <ToolUtils.h>    /* BYU - for GetIndString() */
  32. #include <CodeFragments.h> /* only for debugging */
  33. #include "TelnetHeader.h"
  34. #include "string_resrcdefs.h"
  35. #include "InternalEvents.h"
  36. #include "netevent.proto.h"
  37. #include "menuseg.proto.h"
  38. #include "network.proto.h"
  39. #include "mydnr.proto.h"
  40. #include "macutil.proto.h"
  41. #include "macbinary.h"
  42. #include "binsubs.proto.h"
  43. #include "maclook.proto.h"
  44. #include "bkgr.proto.h"
  45. #include "telneterrors.h"
  46. #include "wind.h"
  47. #include "mainseg.proto.h"
  48. #include "translate.proto.h"
  49. #include "DlogUtils.proto.h"        // For WriteZero proto
  50.  
  51. #include "vsdata.h"
  52. #include "vsinterf.proto.h"
  53.  
  54. extern WindRec *ftplog;
  55. extern TelInfoRec *TelInfo;
  56.  
  57. #define PFTP 1
  58. #define PRCP 2
  59. #define PDATA 3
  60. #define HTELNET 23
  61. #define HRSHD 514
  62. #define HFTP 21
  63. #define BUFFERS 8000
  64. #define PATHLEN 256
  65. #define MACBINARY
  66. #define RCPSEGSIZE 512
  67. #define O_RAW O_RDONLY
  68. #define EOLCHAR 13
  69. #define FASCII 0
  70. #define FIMAGE O_RAW
  71. #define FAMODE 0
  72. #define FIMODE 1
  73. #define FMMODE 2            /* Mac Binary, when ready */
  74.  
  75. MBFile
  76.     *mbfp=NULL;
  77.  
  78. char *nextfile;
  79.  
  80. Handle mungbuf;
  81.  
  82. static short fcnt=0;
  83. static  short
  84.     ftpenable=0,                /* is file transfer enabled? */
  85.     rcpenable=0,                /* is rcp enabled? */
  86.     rsnum=-1,                    /* port number for incoming rshell */
  87.     rserr=-1;                    /* port number for rshd() stderr */
  88.  
  89. static  unsigned char *xs=0L,    /* buffer space for file transfer */
  90.         *pathname=0L,            /* space to keep path names */
  91.         *newfile=0L,            /* current file being received */
  92.         myuser[17],                    /* user name on my machine */
  93.         waitchar;                    /* character waiting for from net */
  94.  
  95. static short 
  96.     curstate = -1,            /* state machine for background processes */
  97.     retstate = 200,            /* to emulate a subroutine call */
  98.     ftpstate = 0,            /* state of the ftp data transfer */
  99.     isdir=0,                /* flag for rcp target pathname */
  100.     waitpos=0,                /* marker for gathering strings from net */
  101.     cnt=0,                    /* number of characters from last netread() */
  102.     fh=0,                    /* file handle when transfer file is open */
  103.     ftpfh=0,                /* file handle for ftp data */
  104.     rc=0,                    /* telnet flag */
  105.     xp=0,                    /* general pointer */
  106.     towrite=0,                /* file transfer pointer */
  107.     len=0;                    /* file transfer length */
  108.  
  109. static long
  110.     filelen=0L;                /* length of current file for transfer */
  111.  
  112. short mainport[NPORTS];        /* BYU 2.4.16 - map FTP data port to main port */
  113. short dataport[NPORTS];        /* BYU 2.4.16 - map FTP main port to data port */
  114. short mainstate[NPORTS];    /* BYU 2.4.16 */
  115. short datastate[NPORTS];    /* BYU 2.4.16 */
  116. short retnstate[NPORTS];
  117.  
  118. ip_port    fileport[NPORTS];
  119.  
  120. static char crfound=0;
  121.  
  122. static short rfstate,
  123.     ftptmode=FAMODE;            /* how to transfer the file on net */
  124.  
  125. static    ip_addr    portaddr[NPORTS],
  126.                 hishostaddr;
  127. static    ip_port    portremoteport[NPORTS],
  128.                 portlocalport[NPORTS];
  129.                 
  130. unsigned char messs[100];        /* BYU */
  131.  
  132. char    ListingTemplate[256];
  133. CInfoPBRec    theDirectoryState;
  134.  
  135. static    void CRESP(short fnum, short msg_number);
  136. static    short ftpgo( short fnum);
  137.  
  138. void    FTPServerUnload(void) {}
  139.  
  140. void CRESP(short fnum, short msg_number)
  141. {
  142.   GetIndString(messs,MSG_RESOURCE_ID,msg_number+1);
  143.   netpush(fnum);
  144.   netwrite(fnum, &messs[1], (short)messs[0]);
  145. }
  146.  
  147. void ftpmess( char *cp)
  148. {
  149.     short temp;
  150.     temp=strlen(cp);
  151.     if (temp>80 || temp < 1) return;
  152.     VSwrite(ftplog->vs,cp,temp);
  153. }
  154.  
  155. /***********************************************************************/
  156. void StartUpFTP(void)
  157. {
  158.     if (gFTPServerPrefs->ServerState != 0)
  159.         setftp();
  160.     else
  161.         unsetftp();
  162. }
  163.  
  164. void setftp( void)
  165. {
  166.     short fnum,i1;                            /* BYU 2.4.16 */
  167.     short size = 1024;
  168. /* set up to receive a telnet connection for ftp commands */
  169.     rfstate = 0;
  170.     ftpstate = 0;
  171. /* Listen for FTP if we're not listening already */
  172.  
  173.     for (i1 = 0; i1 < NPORTS; i1++)                                         /* BYU 2.4.16 */
  174.         if (GetPortType(i1) == PFTP)
  175.             break;                                                            /* BYU 2.4.16 */
  176.  
  177.     if (i1 >= NPORTS) {                                /* BYU 2.4.16 - non-SLIP listen */
  178.         fnum = netlisten(HFTP);        /* BYU 2.4.16 - MacTCP listen */
  179.         ftpenable = 1;                                /* BYU 2.4.16 */
  180.  
  181.         if (fnum >= 0) {                            /* BYU 2.4.16 - signal that events should be caught */
  182.             SetPortType(fnum, PFTP);
  183.             dataport[fnum] = -1;                    /* BYU 2.4.16 - no data needed yet */
  184.             mainstate[fnum] = 0;                    /* BYU 2.4.16 */
  185.             datastate[fnum] = 0;                    /* BYU 2.4.16*/
  186.             retnstate[fnum] = 200;                    /* BYU 2.4.16 */
  187.         }                                            /* BYU 2.4.16 */
  188.     }                                                /* BYU 2.4.16 */
  189.  
  190.     strcpy((char *) myuser,"unknown");                /* BYU LSC - set unknown user name */
  191.     
  192.     mungbuf = NewHandle(size);
  193.     
  194.     while (size--) *(char *)(*mungbuf)++ = 0;
  195. }
  196.  
  197. void unsetftp( void)
  198. {
  199.     short i1;                            /* BYU 2.4.16 */
  200.  
  201.     rfstate = 0;
  202.     ftpstate = 0;
  203.     for (i1 = 0; i1 < NPORTS; i1++) {    /* BYU 2.4.16 */
  204.         if (GetPortType(i1) == PFTP) {        /* BYU 2.4.16 */
  205.             netclose(i1);                /* BYU 2.4.16 */
  206.             SetPortType(i1, NO_TYPE);            /* BYU 2.4.16 */
  207.             mainstate[i1] = 0;            /* BYU 2.4.16 */
  208.             datastate[i1] = 0;            /* BYU 2.4.16*/
  209.         }                                /* BYU 2.4.16 */
  210.     }                                    /* BYU 2.4.16 */
  211. /*    fnum = -1;                            /* BYU 2.4.16 */
  212.     ftpenable = 0;
  213. }
  214.  
  215.  
  216. #if 0        /* BYU - Converted to STR# resource number 23227 */
  217. /***********************************************************************/
  218. /*
  219. *  resident ftp server -- enables initiation of ftp without a username
  220. *  and password, as long as this telnet is active at the same time
  221. *  Now checks for the need of passwords.
  222. */
  223.  
  224. static char *messs[] = {
  225.                         "220 Macintosh Resident FTP server, ready \015\012",
  226.                         "451 Error in processing list command \015\012",
  227.                         "221 Goodbye \015\012",                        /*2*/
  228.                         "200 This space intentionally left blank <   > \015\012",
  229.                         "150 Opening connection \015\012",
  230.                         "226 Transfer complete \015\012",            /*5*/
  231.                         "200 Type set to A, ASCII transfer mode \015\012",
  232.                         "200 Type set to I, binary transfer mode \015\012",
  233.                         "500 Command not understood \015\012",        /*8*/
  234.                         "200 Okay \015\012",
  235.                         "230 User logged in \015\012",
  236.                         "550 File not found \015\012",                /*11*/
  237.                         "501 Directory not present or syntax error\015\012",
  238.                         "250 Chdir okay\015\012",
  239.                         "257 \"",
  240.                         "\" is the current directory \015\012",        /*15*/
  241.                         "501 File not found \015\012",
  242.                         "504 Parameter not accepted, not implemented\015\012",
  243.                         "200 Stru F, file structure\015\012",
  244.                         "200 Mode S, stream mode\015\012",        /*19*/
  245.                         "202 Allocate and Account not required for this server\015\012",
  246.                         "501 Cannot open file to write, check for valid name\015\012",
  247.                         "530 USER and PASS required to activate me\015\012",
  248.                         "331 Password required\015\012",      /*23 */
  249.                         "530 Login failed\015\012",
  250.                         "200 MacBinary Mode enabled\015\012",
  251.                         "200 MacBinary Mode disabled\015\012",  /*26 */
  252.                         "552 Disk write error, probably disk full\015\012",
  253.                         "214-NCSA Telnet FTP server, supported commands:\015\012",
  254.                         "    USER  PORT  RETR  ALLO  PASS  STOR  CWD  XCWD  XPWD  LIST  NLST\015\012",
  255.                         "    HELP  QUIT  MODE  TYPE  STRU  ACCT  NOOP  MACB\015\012",  /*30*/
  256.                         "    MACB is MacBinary and must be done with TYPE I\015\012",
  257.                         "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012",
  258.                         "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012",                /* 33 */
  259.                         "200 Type set to I, binary transfer mode [macbinary disabled]\015\012",
  260.                 ""};
  261.  
  262. #endif
  263.  
  264. /* open the FTP data connection to the remote host */
  265. short ftpgo( short fnum)
  266. {
  267.     short    ftpdata;
  268.  
  269.     netfromport(20);                 /* ftp data port */
  270.     ftpdata = netxopen(portaddr[fnum],fileport[fnum], 15);
  271.     mainport[ftpdata] = fnum;
  272.     dataport[fnum] = ftpdata;
  273.     return(ftpdata);
  274. }
  275.  
  276. void rftpd
  277.   (
  278.     short code,                                /* BYU 2.4.16 */
  279.     short fnum                                /* BYU 2.4.16 */
  280.   )
  281. {
  282.     ip_port    fdport;
  283.     short    ftpdata, i, append = 0;
  284.     char    tempp[256], theDir[256];
  285.     char updir[4];                        /* JMB 2.6 */
  286.     
  287.     if (!ftpenable)
  288.         return;
  289.  
  290.     netpush(fnum);
  291.  
  292.     rfstate = mainstate[fnum];                /* BYU 2.4.16 */
  293.     ftpstate = datastate[fnum];                /* BYU 2.4.16 */
  294.     retstate = retnstate[fnum];                /* BYU 2.4.16 */
  295.     fdport = fileport[fnum];                /* BYU 2.4.16 */
  296.  
  297.     switch (rfstate) {
  298.         case 0:
  299.             if (code != CONOPEN) 
  300.                 break;
  301.             ftptmode = FAMODE;
  302.             netputevent(USERCLASS,FTPCOPEN,-1,0);
  303.             if (!xs) xs=(unsigned char *)NewPtrClear(BUFFERS+10);    /* BYU LSC */
  304.             if (!pathname) pathname=(unsigned char *)NewPtrClear(PATHLEN);
  305.             if (!newfile) newfile=(unsigned char *)NewPtrClear(PATHLEN);
  306.             if (!xs || !pathname || !newfile)    /* no memory for ftp names */
  307.                 {
  308.                 DoError(114 | MEMORY_ERRORCLASS, LEVEL3, NULL);
  309.                 quit();                    // Should we really quit?
  310.                 }    
  311.         
  312.             rfstate = 1;                /* drop through */
  313.         case 1:
  314.             CRESP(fnum,0);                            /* BYU 2.4.16 */
  315.             netgetftp(fnum, &portaddr[fnum], &portlocalport[fnum], &portremoteport[fnum]);        /* BYU 2.4.16 - get default ftp information */
  316.             hishostaddr = portaddr[fnum];
  317.             fdport = portremoteport[fnum];
  318.  
  319.             waitpos = 0; waitchar = '\012';
  320.             rfstate = 50;               /* note skips over */
  321.             if ((gFTPServerPrefs->ServerState == 2)) 
  322.                 retstate = 3;                /* check pass */
  323.             else
  324.                 retstate = 5;                /* who needs one ? */
  325.             break;
  326.         case 3:                /* check for passwords */
  327.         case 4:
  328.             waitpos = 0;  waitchar = '\012';
  329.             rfstate = 50;  
  330.             if (!strncmp("USER",(char *) xs,4)) {    /* BYU LSC */
  331.                 if (strlen((char *) xs) < 6)        /* BYU LSC - make sure blank name stays blank */
  332.                     xs[5] = myuser[0] = 0;
  333.                 strncpy((char *) myuser,(char *) &xs[5],16);        /* BYU LSC - keep user name */
  334.                 FTPLogUserLoggingIn();
  335.                 CRESP(fnum,23);                                        /* BYU 2.4.16 */
  336.                 retstate = 4;        /* wait for password */
  337.                 break;
  338.             }
  339.             if (!strncmp("PASS",(char *) xs,4)) {                    /* BYU LSC */
  340.                 if (Scheckpass((char *) myuser,(char *) &xs[5])) {    /* BYU LSC */
  341.                     ftpmess("FTP password OK - logged in\015\012");
  342.                     CRESP(fnum,10);                                    /* BYU 2.4.16 */
  343.                     retstate = 5;
  344.                 }
  345.                 else {
  346.                     ftpmess("FTP password failed - access denied\015\012");
  347.                     CRESP(fnum,24);                                    /* BYU 2.4.16 */
  348.                     retstate = 3;
  349.                 }
  350.                 break;
  351.             }
  352.             if (!strncmp("QUIT",(char *) xs,4)) {    /* BYU LSC */
  353.                 CRESP(fnum,2);                        /* BYU 2.4.16 */
  354.                 cnt = -1;
  355.             }
  356.             else {
  357.                 CRESP(fnum,22);        /* BYU 2.4.16 */
  358.             }
  359.             retstate = 3;            /* must have password first */
  360.             break;                
  361.                 
  362. /* interpret commands that are received from the other side */
  363.             
  364.         case 5:
  365.  
  366. /* set to a safe state to handle recursion, wait for another command line from client */
  367.             rfstate = 50;
  368.             retstate = 5;
  369.             waitchar = '\012';
  370.             waitpos = 0;
  371.  
  372.             if (!strncmp((char *) xs,"LIST",4) || !strncmp((char *) xs,"NLST",4)) {    /* BYU LSC */
  373.                 if ((strlen((char *) xs) < 6) || xs[5] == '.')        /* BYU LSC */
  374.                     strcpy((char *) xs,"LIST *");                    /* BYU LSC */
  375.                 strcpy(ListingTemplate, (char *) &xs[5]);
  376.                 nextfile = firstname(ListingTemplate, TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, &theDirectoryState);    /* find first name */
  377.                 if (nextfile == NULL) {
  378.                     CRESP(fnum,16);                /* BYU 2.4.16 */
  379.                 }
  380.                 else {
  381.                     Str255    tempstr;
  382.                     char    tempstr2[256];
  383.                     ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open the connection */
  384.                     fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */
  385.  
  386.                     if (ftpdata >= 0)
  387.                         SetPortType(ftpdata, PDATA);
  388.                     ftpstate = 40;        /* ready to transmit */
  389.                     CRESP(fnum,4);                            /* BYU 2.4.16 */
  390.                     PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, tempstr);
  391.                     PtoCstr(tempstr);
  392.                     sprintf(tempstr2, "FTP Sending Directory %s\015\012", (char *)tempstr);
  393.                     ftpmess(tempstr2);
  394.                 }
  395.             }
  396.             else if (!strncmp((char *) xs,"CWD",3)) {    /* BYU LSC */
  397.                 if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) {
  398.                     CRESP(fnum,12);                        /* BYU 2.4.16 */
  399.                 }
  400.                 else {                        /* success */
  401.                     CRESP(fnum,13);            /* BYU 2.4.16 */
  402.                 }
  403.             }
  404.             else if (!strncmp((char *) xs,"CDUP",4)) {        /* JMB 2.6 */
  405.                 strcpy(updir, "..");                        /* JMB 2.6 */
  406.                 if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), updir)) {                /* JMB 2.6 */
  407.                     CRESP(fnum,12);                            /* JMB 2.6 */
  408.                 }                                            /* JMB 2.6 */
  409.                 else {                                        /* JMB 2.6 */
  410.                     CRESP(fnum,13);                            /* JMB 2.6 */
  411.                 }                                            /* JMB 2.6 */
  412.             }                                                /* JMB 2.6 */
  413.             else if (!strncmp((char *) xs,"STOR",4) || !strncmp((char *) xs,"APPE", 4))
  414.               {
  415.                 short    MBflag;
  416.  
  417.                 if (!strncmp((char *) xs,"APPE", 4)) {
  418.                     if (ftptmode != FASCII) {
  419.                         CRESP(fnum, 35);
  420.                         break;
  421.                         }
  422.                     else
  423.                         append = 1;
  424.                     }
  425.                     
  426.                 /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  427.                 if ((!TelInfo->MacBinary) || (ftptmode == FAMODE))
  428.                     MBflag = MB_DISABLE;
  429.                 else
  430.                     MBflag = 0;
  431.                     
  432.                 if (ftptmode == FAMODE)    MBflag |= MB_ISASCII;
  433.                 if (append) MBflag |= MB_APPEND;
  434.                 append = 0;
  435.                 
  436.                 mbfp = MBopen((char *)&xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, (short)(MB_WRITE | MBflag));
  437.                 if (mbfp == 0L)
  438.                   {
  439.                     CRESP(fnum,21);            /* BYU 2.4.16 */
  440.                     break;
  441.                   }
  442.                 else
  443.                     ftpfh = 12;
  444.  
  445.                 ftpstate = 0;
  446.  
  447.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  448.                 
  449.  
  450.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  451.                 fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */
  452.  
  453.                 if (ftpdata >= 0)
  454.                     SetPortType(ftpdata, PDATA);
  455.  
  456.                 CRESP(fnum,4);        /* BYU 2.4.16 */
  457.  
  458.                 ftpstate = 30;        /* ready for data */
  459.               }
  460.  
  461.             else if (!strncmp((char *) xs,"RETR",4))    /* BYU LSC */
  462.               {
  463.               /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */
  464.                 short
  465.                     MBflag;
  466.                 if ((!TelInfo->MacBinary) || (ftptmode == FAMODE))
  467.                     MBflag = MB_DISABLE;
  468.                 else
  469.                     MBflag = 0;
  470.                     
  471.                 if (ftptmode == FAMODE)    MBflag |= MB_ISASCII;
  472.                 
  473.                 mbfp = MBopen((char *) &xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, MB_READ | MBflag);
  474.                 
  475.                 if (mbfp == 0L) {
  476.                     CRESP(fnum,11);                        /* BYU 2.4.16 */
  477.                     break;
  478.                 }
  479.                 ftpfh = 12;
  480.  
  481.                 strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1);    /* BYU LSC */
  482.  
  483.                 PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir);
  484.                 PtoCstr((StringPtr) theDir);
  485.                 sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile);
  486.                 ftpmess(tempp);
  487.  
  488.                 ftpdata = ftpgo(fnum);                /* BYU 2.4.16 - open connection */
  489.                 fdport = portremoteport[fnum];
  490.  
  491.                 ftpstate = 20;        /* ready for data */
  492.                 if (ftpdata >= 0)
  493.                     SetPortType(ftpdata, PDATA);
  494.  
  495.                 CRESP(fnum,4);                            /* BYU 2.4.16 */
  496.               }
  497.             else if (!strncmp((char *) xs,"TYPE",4)) {    /* BYU LSC */
  498.                 if (toupper(xs[5]) == 'I') {
  499.                     ftptmode = FIMODE;
  500.                     if (TelInfo->MacBinary) {
  501.                         CRESP(fnum,33);                    /* BYU 2.4.16 - Binary on, MACB ON */
  502.                         }
  503.                     else {
  504.                         CRESP(fnum,34);                    /* BYU 2.4.16 - Binary on, MACB off */
  505.                         }
  506.                 }
  507.                 else if (toupper(xs[5]) == 'A') {
  508.                     ftptmode = FAMODE;
  509.                     CRESP(fnum,6);                    /* BYU 2.4.16 */
  510.                     }
  511.                 else {
  512.                     CRESP(fnum,17);                    /* BYU 2.4.16 */
  513.                 }
  514.  
  515.             }
  516.             else if (!strncmp((char *) xs,"MACB",4)) {    /* BYU LSC */
  517.                 if (toupper(xs[5]) == 'E') {
  518.                     TelInfo->MacBinary = 1;
  519.                     CRESP(fnum,25);                    /* BYU 2.4.16 */
  520.                 }
  521.                 else {
  522.                     TelInfo->MacBinary = 0;
  523.                     CRESP(fnum,26);                    /* BYU 2.4.16 */
  524.                 }
  525.                 DisplayMacBinary();            /* post an event ? */
  526.             }
  527.             else if (!strncmp((char *) xs,"PORT",4)) {    
  528. /*    get the requested port number from the command given */
  529.                 ip_addrbytes    tempaddr;
  530.                 unsigned char     *stringPtr, *tempPtr, storage[10];
  531.                 long            numbers[6];
  532.                 short index;
  533.  
  534.                 for (tempPtr = stringPtr = &xs[5], index = 0; (*stringPtr != '\0') && (index < 6);index++) {
  535.                     while ((*tempPtr != '\0') && (*tempPtr != ',')) { tempPtr++; };
  536.                      BlockMoveData(stringPtr, &(storage[1]), tempPtr-stringPtr);
  537.                      storage[0] = tempPtr-stringPtr;
  538.                      StringToNum(storage, &numbers[index]);
  539.                      tempPtr++;
  540.                      stringPtr = tempPtr;
  541.                  }
  542.                 
  543.                 tempaddr.a.byte[0] = (char) numbers[0];
  544.                 tempaddr.a.byte[1] = (char) numbers[1];
  545.                 tempaddr.a.byte[2] = (char) numbers[2];
  546.                 tempaddr.a.byte[3] = (char) numbers[3];
  547.                 portaddr[fnum] = tempaddr.a.addr;
  548.                 portlocalport[fnum] = numbers[4]*256 + numbers[5];
  549.                 fdport = portlocalport[fnum];
  550.                 CRESP(fnum,3);                            
  551.             }
  552.             else if (!strncmp((char *) xs,"QUIT",4)) {    /* BYU LSC */
  553.                 CRESP(fnum,2);                            /* BYU 2.4.16 */
  554.                 rfstate = 60;
  555.                 netputuev(CONCLASS,CONDATA,fnum,0);    /* post back to me */
  556.             }
  557.             else if (!strncmp((char *) xs,"XPWD",4) || !strncmp((char *) xs,"PWD",3)) {    /* BYU LSC */
  558.                 CRESP(fnum,14);                        /* BYU 2.4.16 - start reply */
  559.                 PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) xs);
  560.                 PtoCstr((StringPtr) xs);
  561.                 netwrite(fnum,(char *) xs,strlen((char *) xs));    /* BYU LSC - write dir name */
  562.                 CRESP(fnum,15);                        /* BYU 2.4.16 - finish reply */
  563.             }
  564.             else if (!strncmp((char *) xs,"USER",4)) {    /* BYU LSC */
  565.                 if (strlen((char *) xs) < 6)            /* BYU LSC - make sure blank name stays blank */
  566.                     xs[5] = myuser[0] = 0;
  567.                 strncpy((char *) myuser,(char *) &xs[5],16);    /* BYU LSC - keep user name */
  568.                 FTPLogUserLoggingIn();
  569.                 /* confirm log in without password */
  570.                 CRESP(fnum,10);                            /* BYU 2.4.16 */
  571.             }
  572.             else if (!strncmp((char *) xs,"STRU",4)) {    /* BYU LSC - only one stru allowed */
  573.                 if (xs[5] == 'F') {
  574.                     CRESP(fnum,18); }                    /* BYU 2.4.16 */
  575.                 else {
  576.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  577.             }
  578.             else if (!strncmp((char *) xs,"MODE",4)) {    /* BYU LSC - only one mode allowed */
  579.                 if (xs[5] == 'S') {
  580.                     CRESP(fnum,19); }                    /* BYU 2.4.16 */
  581.                 else {
  582.                     CRESP(fnum,17); }                    /* BYU 2.4.16 */
  583.             }
  584.             else if (!strncmp((char *) xs,"ALLO",4) || !strncmp((char *) xs,"ACCT",4)) {    /* BYU LSC */
  585.                 CRESP(fnum,20); }                        /* BYU 2.4.16 */
  586.             else if (!strncmp((char *) xs,"HELP",4)) {    /* BYU LSC */
  587.                 for (i=28; i<33; i++) {
  588.                     CRESP(fnum,i); }                    /* BYU 2.4.16 */
  589.             }
  590.             else if (!strncmp((char *) xs,"NOOP",4)) {        /* BYU LSC */
  591.                 CRESP(fnum,9); }                            /* BYU 2.4.16 */
  592.             else if (!strncmp((char *) xs,"SYST",4)) {    // JMB 2.6
  593.                   netpush(fnum);                        // JMB 2.6
  594.                   netwrite(fnum, "225 MACOS System Version:\015\012", 27);    // JMB 2.6
  595.                     }    // JMB 2.6
  596.             else {            /* command not understood */
  597.                 CRESP(fnum,8);                                 /* BYU 2.4.16 */
  598.             }
  599.  
  600.             break;
  601.  
  602. /*    subroutine to wait for a particular character */
  603.         case 50:
  604.             while (0 < (cnt = netread(fnum,&xs[waitpos],1))) {
  605.                 if (xs[waitpos] == waitchar) {
  606.                     rfstate = retstate;
  607.  
  608.                     while (xs[waitpos] < 33)        /* find end of string */
  609.                         waitpos--;
  610.                     xs[++waitpos] = '\0';            /* put in terminator */
  611.  
  612.                     for (i=0; i<4; i++)                /* want upper case */
  613.                         xs[i] = toupper(xs[i]);
  614.  
  615.                     break;
  616.                 }
  617.                 else
  618.                     waitpos += cnt;
  619.  
  620.             }
  621.             break;
  622.  
  623.         case 60:                    /* wait for message to get through */
  624.                                     /* or connection is broken */
  625. /*            printf("                  %d,%d",netpush(fnum),netest(fnum));*/
  626.             if (!netpush(fnum) || netest(fnum))
  627.                 cnt = -1;
  628.             else
  629.                 netputuev(CONCLASS,CONDATA,fnum,0);    /* post back to me */
  630.             break;
  631.  
  632.         default:
  633.             break;
  634.  
  635.     }
  636.  
  637.     if (cnt < 0) {
  638.         if (mbfp) {
  639.             MBclose( mbfp );
  640.             mbfp = NULL;
  641.         }
  642.         ftpdata = dataport[fnum];                    /* BYU 2.4.16 */
  643.         if (ftpdata > 0) {
  644.             netclose(ftpdata);
  645.             netputevent(USERCLASS,FTPEND,-1,0);
  646.             dataport[fnum] = -1;                    /* BYU 2.4.16 */
  647.             mainport[ftpdata] = -1;                    /* BYU 2.4.16 */
  648.         }
  649.         rfstate = 100;
  650.         ftpstate = 0;
  651.         cnt = 0;
  652.         netclose(fnum);
  653.         SetPortType(fnum, NO_TYPE);
  654.         netputevent(USERCLASS,FTPCLOSE,-1,0);
  655. #if 0                                                /* BYU 2.4.16 */
  656.         fnum = -1;
  657.         ftpdata = -1;
  658. #endif                                                /* BYU 2.4.16 */
  659.         setftp();                /* reset it */
  660.     }
  661.  
  662.     mainstate[fnum] = rfstate;                        /* BYU 2.4.16 */
  663.     datastate[fnum] = ftpstate;                        /* BYU 2.4.16 */
  664.     retnstate[fnum] = retstate;                        /* BYU 2.4.16 */
  665.     fileport[fnum] = fdport;                        /* BYU 2.4.16 */
  666.  
  667. }
  668.  
  669. /*    important note:  for Sfread, nwant must be 256 bytes LARGER than the amount
  670.     which will probably be read from the connection.
  671.     Sfread will stop anywhere from 0 to 256 bytes short of filling nwant
  672.     number of bytes. */
  673.     
  674. long Sfread( short pnum, char *buf, long nwant)
  675. {
  676.     long    i, ndone, lim;
  677.     char    *p, *q;
  678.  
  679.     if (nwant < 1024)
  680.         return(-1);
  681.  
  682.     ndone = 0;
  683.  
  684.     HLock(mungbuf);
  685.     while (ndone < nwant - 1024) {
  686.  
  687.         if (0 >= (lim = netread(pnum,*mungbuf,1024))) {
  688.             if (ndone || !lim)            /* if this read is valid, but no data */
  689.                 return(ndone);
  690.             else
  691.                 return(-1);                /* if connection is closed for good */
  692.         }
  693.  
  694.         p = *mungbuf;
  695.         q = (char *) buf + ndone;
  696.  
  697. /*        printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant);
  698.         n_row();
  699. */
  700.         for (i=0; i < lim; i++) {
  701.  
  702.             if (crfound) {
  703.                 if (*p == 10)
  704.                     *q++ = EOLCHAR;
  705.                 else if (*p == 0)
  706.                     *q++ = 13;            /* CR-NUL means CR */
  707.                 crfound = 0;
  708.             }
  709.             else if (*p == 13)
  710.                 crfound = 1;
  711.             else
  712.                 if (gFTPServerPrefs->DoISOtranslation)
  713.                 {
  714.                     *q++ = (char) ftp_iso_mac((unsigned char *)p);        /* transform to mac */
  715.                 }
  716.                 else
  717.                     *q++ = *p;                /* copy the char */
  718.  
  719.             p++;
  720.         }
  721.  
  722.         ndone = q-buf;                    /* count chars ready */
  723.     }
  724.     
  725.     HUnlock(mungbuf);
  726.     
  727.     return(ndone);
  728. }
  729.  
  730. /***************************************************************************/
  731. /*  Sfwrite
  732. *   Write an EOL translated buffer into netwrite.
  733. *   Returns the number of bytes which were processed from the incoming
  734. *   buffer.  Uses its own 1024 byte buffer for the translation (with Sfread).
  735. */
  736.  
  737. long Sfwrite( short pnum, void *buf, long nsrc)
  738. {
  739.     long    i,ndone,nout,lim;
  740.     char    *p,*q;
  741.  
  742.     ndone = 0;
  743.  
  744.     while (ndone < nsrc) {
  745.  
  746.         if (0 > ( i = netroom(pnum)))
  747.             return(-1);
  748.  
  749.         if (i < 1024)                    /* not enough room to work with */
  750.             return(ndone);
  751.  
  752. /*    process up to 512 source bytes for output (could produce 1K bytes out) */
  753.         if (nsrc - ndone > 512)
  754.             lim = 512;
  755.         else
  756.             lim = nsrc-ndone;
  757.  
  758.         p = (char *) buf + ndone;                /* where to start this block */
  759.         q = *mungbuf;                    /* where munged stuff goes */
  760.         for (i=0; i < lim; i++) {
  761.             if (*p == EOLCHAR) {
  762.                 *q++ = 13;
  763.                 *q++ = 10;
  764.                 p++;
  765.             }
  766.             else
  767.                 if (gFTPServerPrefs->DoISOtranslation)
  768.                 {
  769.                     *q++ = (char) ftp_mac_iso((unsigned char *)p);        /* transform to ISO */
  770.                     p++;
  771.                 }
  772.                 else
  773.                     *q++ = *p++;
  774.         }
  775.         ndone += lim;                    /* # of chars processed */
  776.         nout = q-*mungbuf;                /* # of chars new */
  777.  
  778.         HLock (mungbuf);
  779.         
  780.         if ( nout != netwrite(pnum,*mungbuf,nout) )        /* Some error in Sfwrite */
  781.             DoError (201 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  782.         
  783.         HUnlock (mungbuf);
  784.     }
  785.  
  786.     return(ndone);
  787. }
  788.  
  789.  
  790. /*    FTP receive and send file functions */
  791.  
  792. void ftpd
  793.   (
  794.     short code,
  795.     short ftpdata                            /* BYU 2.4.16 */
  796.   )
  797. {
  798.     short fnum = mainport[ftpdata];        /* BYU 2.4.16 */
  799.     short i,a;
  800.     char tempp[256];
  801.     char theDir[256];
  802.  
  803.  
  804.     ftpstate = datastate[fnum];            /* BYU 2.4.16 */
  805.  
  806.     switch (ftpstate) {
  807.         default:
  808.             break;
  809.  
  810.         case 40:                /* list file names in current dir */
  811.  
  812.             if (code == CONFAIL)    /* something went wrong */
  813.                 fcnt = -1;
  814.             if (code != CONOPEN)     /* waiting for connection to open */
  815.                 break;
  816.             
  817.             ftpstate = 41;
  818.  
  819. /*
  820. *  send the "nextfile" string and then see if there is another file
  821. *  name to send
  822. */
  823.         case 41:
  824.             netputuev(SCLASS,FTPACT,ftpdata,0);
  825.             netpush(ftpdata);
  826.             strcpy(tempp,nextfile);                    /* BYU 2.4.13 */
  827.             strcat(tempp,"\015\012");                /* BYU 2.4.13 */
  828.             i = strlen(tempp);                        /* BYU 2.4.13 */
  829.             if (gFTPServerPrefs->DoISOtranslation)
  830.                 trbuf_mac_ftp((unsigned char *)tempp, i);        /* transform to ISO */ //PETERL?
  831.             if (i != netwrite(ftpdata,tempp,i)) {    /* BYU 2.4.13 */
  832.                 CRESP(fnum,1);                        /* BYU 2.4.16 */
  833.                 fcnt = -1;
  834.                 break;
  835.             }
  836.  
  837.             if (NULL == (nextfile = nextname(ListingTemplate, &theDirectoryState))) {    /* normal end */
  838.                 ftpstate = 22;               /* push data through */
  839.             }
  840.             break;
  841.             
  842.         case 30:
  843.             if (code == CONFAIL)    /* something went wrong */
  844.                 fcnt = -1;
  845.             if (code != CONOPEN)    /* waiting for connection to open */
  846.                 break;
  847.             ftpstate = 31;
  848.             crfound = 0;
  849.             len = xp = 0;
  850.             filelen = 0L;
  851.             PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir);
  852.             PtoCstr((StringPtr) theDir);
  853.             sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile);
  854.             ftpmess(tempp);
  855.             netputevent(USERCLASS,FTPBEGIN,-2,0);
  856.             
  857.         case 31:
  858. /*
  859. * file has already been opened, take everything from the connection
  860. * and place into the open file: ftpfh
  861. */
  862.             do {
  863.             /* wait until xs is full before writing to disk */
  864.                 if (len <= 2000) {
  865.  
  866.                     if (xp) {
  867.                         if (0 > MBwrite(mbfp, xs, xp)) {
  868.                             DoError (202 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  869.  
  870.                             MBclose( mbfp);            /* Close on Disk Full Error */
  871.                             ftpstate=22;
  872.                             CRESP(fnum,27);                /* BYU 2.4.16 */
  873.                             ftpmess((char *) messs);    /* BYU LSC */
  874.                             if( (a = netclose(ftpdata)) !=0 ) 
  875.                                 DoError (108 | NET_ERRORCLASS, LEVEL1, NULL);
  876.                             fcnt = -1;
  877.                             mbfp=NULL;
  878.                             break;
  879.                         }
  880.                         xp = 0;
  881.                     }
  882.                     len = BUFFERS;        /* expected or desired len to go */
  883.                 }
  884.  
  885.                 if (ftptmode == FAMODE)
  886.                     fcnt = Sfread(ftpdata,(char *) &xs[xp],len);    /* BYU LSC */
  887.                 else
  888.                     fcnt = netread(ftpdata,&xs[xp],len);
  889.  
  890.                 if (fcnt >= 0) {
  891.                     len -= fcnt;
  892.                     xp += fcnt;
  893.                     filelen += fcnt;
  894.                 }
  895.  
  896.                 if (fcnt < 0) {
  897.                     if (0 > MBwrite( mbfp, xs, xp)) {
  898.                         CRESP(fnum,27);            /* BYU 2.4.16 */
  899.                         MBclose( mbfp);            /* Close file on error */
  900.                         break;
  901.                     }
  902.                     MBclose( mbfp );
  903.                     ftpfh = 0;
  904.                     CRESP(fnum,5);                    /* BYU 2.4.16 */
  905.                 }
  906.  
  907.             } while (fcnt > 0);
  908.             break;
  909.  
  910.         case 20:
  911.  
  912.             if (code == CONFAIL)    /* something went wrong */
  913.                 fcnt = -1;
  914.             if (code != CONOPEN)    /* waiting for connection to open */
  915.                 break;
  916.             ftpstate = 21;
  917.             filelen = MBsize( mbfp );
  918.             towrite = 0;
  919.             xp = 0;
  920.             netputevent(USERCLASS,FTPBEGIN,-1,0);
  921.  
  922.         case 21:
  923. /*
  924. *  transfer file(s) to the other host via ftp request
  925. *  file is already open = ftpfh
  926. */
  927.             netputuev(SCLASS,FTPACT,ftpdata,0);
  928.         
  929.             if (towrite <= xp) {
  930.  
  931.                 i = BUFFERS;
  932.                 towrite = MBread( mbfp, xs, i);
  933.                 xp = 0;
  934.             }
  935.  
  936.             if (towrite <= 0 || netest(ftpdata)) {        /* we are done */
  937.                 ftpstate = 22;
  938.                 break;
  939.             }
  940.  
  941.             if (ftptmode == FAMODE)
  942.                 i = Sfwrite(ftpdata,&xs[xp],towrite-xp);
  943.             else
  944.                 i = netwrite(ftpdata,&xs[xp],towrite-xp);
  945.  
  946.  
  947.  
  948.             if (i > 0) {
  949.                 xp += i;
  950.                 filelen -= i;
  951.                 if (filelen < 0L)
  952.                     filelen = 0L;
  953.             }
  954.  
  955.             break;
  956.  
  957.         case 22:        /* wait for data to be accepted */
  958.             netputuev(SCLASS,FTPACT,ftpdata,0);
  959.  
  960.             fcnt = netpush(ftpdata);        /* will go negative on err */
  961.             if (!fcnt || netest(ftpdata))
  962.                 fcnt = -1;
  963.             if (fcnt < 0) {
  964.                 CRESP(fnum,5);                /* BYU 2.4.16 */
  965.             }
  966.             break;
  967.  
  968.         case 0:
  969.             break;
  970.  
  971.     }  /* end of switch */
  972.  
  973. /*    after reading from connection, if the connection is closed, reset up shop. */
  974.     if (fcnt < 0) {
  975.         if (mbfp) {
  976.             MBclose( mbfp );
  977.             mbfp = NULL;
  978.         }
  979.         ftpstate = 0;
  980.         fcnt = 0;
  981.         if (ftpdata >= 0) {
  982.             netclose(ftpdata);
  983.             netputevent(USERCLASS,FTPEND,-1,0);
  984.             mainport[ftpdata] = -1;                /* BYU 2.4.16 */
  985.             dataport[fnum] = -1;                /* BYU 2.4.16 */
  986.         }
  987.     }
  988.  
  989.     datastate[fnum] = ftpstate;            /* BYU 2.4.16 */
  990.  
  991. }
  992.  
  993.  
  994. /* Sftpname and Sftpuser and Sftphost
  995. *  record the name of the file being transferred, to use in the status
  996. *  line updates
  997. */
  998.  
  999. void Sftpname(char *s)
  1000. {
  1001.     strcpy(s, (char *) newfile);    /* BYU LSC */
  1002. }
  1003.  
  1004. ip_addr Sftphost(void)
  1005. {
  1006.     return(hishostaddr);
  1007. }
  1008.  
  1009. void Sftpstat(long *byt)
  1010. {
  1011.     *byt = filelen;
  1012. }
  1013.  
  1014. void FTPLogUserLoggingIn(void)
  1015. {
  1016.     ftpmess("FTP user ");
  1017.     ftpmess((char *) myuser);
  1018.     ftpmess(" logging in\015\012");
  1019. }
  1020.  
  1021. /****************************************************************************/
  1022. /* Sencompass - Compute the encrypted password */
  1023. void Sencompass(char *ps, char *en)
  1024. {
  1025.     short    i,ck;
  1026.     char    *p,c;
  1027.  
  1028.     ck = 0;
  1029.     p = ps;
  1030.     while (*p)                /* checksum the string */
  1031.         ck += *p++;
  1032.  
  1033.     c = ck;
  1034.  
  1035.     for (i=0; i<10; i++) {
  1036.         *en =  (((*ps ^ c) | 32) & 127);     /* XOR with checksum */
  1037.         if (*ps)
  1038.             ps++;
  1039.         else
  1040.             c++;        /* to hide length */
  1041.         en++;
  1042.     }
  1043.  
  1044.     *en = 0;
  1045. } /* Sencompass */
  1046.  
  1047. /****************************************************************************/
  1048. /* Scompass - compute and check the encrypted password */
  1049. Boolean Scompass(char *ps, char *en)
  1050. {
  1051.     short    ck;
  1052.     char    *p,c;
  1053.  
  1054.     ck = 0;
  1055.     p = ps;
  1056.     while (*p)                /* checksum the string */
  1057.         ck += *p++;
  1058.  
  1059.     c = ck;
  1060.  
  1061.     while (*en) {
  1062.         if ((((*ps ^ c) | 32) & 127) != *en)    /* XOR with checksum */
  1063.             return(FALSE);
  1064.         if (*ps)
  1065.             ps++;
  1066.         else
  1067.             c++;            /* increment checksum to hide length */
  1068.         en++;
  1069.     }
  1070.  
  1071.     return(TRUE);
  1072. }
  1073.  
  1074. /****************************************************************************/
  1075. /*  Scheckpass - Check the password file for the user, password combination */
  1076. Boolean Scheckpass(char *us, char *ps)
  1077. {
  1078.     FTPUser        **FTPUhdl;
  1079.     Str255        scratchPstring;
  1080.     CInfoPBRec    theInfo;
  1081.     
  1082.     strcpy((char *)scratchPstring, us);
  1083.     CtoPstr((char *)scratchPstring);
  1084.     
  1085.     UseResFile(TelInfo->SettingsFile);
  1086.     FTPUhdl = (FTPUser **)Get1NamedResource(FTPUSER, scratchPstring);
  1087.     if (ResError()) return(FALSE);        // User not found
  1088.     
  1089.     HLock((Handle)FTPUhdl);
  1090.     BlockMove((**FTPUhdl).EncryptedPassword, scratchPstring,
  1091.                 Length((**FTPUhdl).EncryptedPassword)+1);
  1092.     PtoCstr(scratchPstring);
  1093.     
  1094.     if (Scompass(ps, (char *)scratchPstring)) {        // Password matches
  1095.         TelInfo->DefaultDirDirID = (**FTPUhdl).DefaultDirDirID;
  1096.         TelInfo->DefaultDirVRefNum = VolumeNameToRefNum((**FTPUhdl).DefaultDirVolName);
  1097.         WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec));
  1098.         theInfo.dirInfo.ioVRefNum = TelInfo->DefaultDirVRefNum;
  1099.         theInfo.dirInfo.ioDrDirID = TelInfo->DefaultDirDirID;
  1100.         theInfo.dirInfo.ioNamePtr = scratchPstring;
  1101.         theInfo.dirInfo.ioFDirIndex = -1;        // Only give me the Directory Info
  1102.         if (PBGetCatInfoSync(&theInfo) != noErr) {
  1103.             TelInfo->DefaultDirDirID = 2;
  1104.             TelInfo->DefaultDirVRefNum = -1;
  1105.             }
  1106.         ReleaseResource((Handle)FTPUhdl);
  1107.         return(TRUE);
  1108.         }
  1109.     
  1110.     ReleaseResource((Handle)FTPUhdl);
  1111.     return(FALSE);                                    // Password was no good
  1112. }
  1113.